package com.mmall.seckill.controller;

import com.mmall.seckill.annotation.AccessLimit;
import com.mmall.seckill.common.CodeMsg;
import com.mmall.seckill.common.Result;
import com.mmall.seckill.common.redis.RedisService;
import com.mmall.seckill.common.redis.keyCode.GoodsKey;
import com.mmall.seckill.common.redis.keyCode.SeckillKey;
import com.mmall.seckill.domain.SeckillUser;
import com.mmall.seckill.service.GoodsService;
import com.mmall.seckill.service.SeckillService;
import com.mmall.seckill.vo.GoodsVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.OutputStream;
import java.util.List;

/**
 * Created by megan on 2018/6/19.
 * 秒杀核心功能
 */
@Slf4j
@Controller
@RequestMapping("/miaosha/")
public class MiaoshaController implements InitializingBean{

    @Resource
    private SeckillService seckillService;
    @Resource
    private GoodsService goodsService;
    @Resource
    private RedisService redisService;

    /**
     * 系统初始化的时候加载这个方法
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        // 把秒杀的商品数量加载到缓存中、
        List<GoodsVo> goodsList = goodsService.listGoodsVo();
        if(CollectionUtils.isNotEmpty(goodsList)){
            for(GoodsVo vo : goodsList){
                redisService.set(GoodsKey.getGoodsStock,vo.getId()+"_",vo.getStockCount() * 2 + "");
            }
        }
    }

    /**
     * 验证码
     * @param response
     * @param goodsId
     * @param user
     * @return
     */
    @RequestMapping("verifyCode.do")
    @ResponseBody
    public Result getVerifyCode(HttpServletResponse response,Long goodsId, SeckillUser user){
        if(user != null){
            try {
                BufferedImage image = seckillService.createMiaoshaVerifyCode(user,goodsId);
                OutputStream out = response.getOutputStream();
                ImageIO.write(image, "JPEG", out);
                out.flush();
                out.close();
                return Result.success();
            }catch(Exception e) {
                log.error("生成验证码图片异常 -> {}",e);
                return Result.coderMsg(CodeMsg.MIAOSHA_FAIL);
            }
        }
        return Result.coderMsg(CodeMsg.SESSION_ERROR);
    }

    /**
     * 秒杀核心业务
     * @param user
     * @param goodsId
     * @return
     */
    @RequestMapping(value = "/{path}/miaosha.do",method = RequestMethod.POST)
    @ResponseBody
    public Result miaosha(SeckillUser user, @RequestParam("goodsId")long goodsId, @PathVariable("path") String path){
        if(user == null){
            return Result.coderMsg(CodeMsg.SESSION_ERROR);
        }
        // path 和redis 对比
        Boolean check = seckillService.checkPath(user,goodsId,path);
        if(check!=null && check){
            return seckillService.miaoshaV2(goodsId,user);
        }
        return Result.coderMsg(CodeMsg.REQUEST_ILLEGAL);
    }

    /**
     * 验证 验证码.获取秒杀地址。
     * @param user
     * @param goodsId
     * @return
     */
    @AccessLimit(seconds=5, maxCount=5, needLogin=true)
    @RequestMapping(value = "getMiaoshaPath.do",method = RequestMethod.GET)
    @ResponseBody
    public Result getMiaoshaPath(HttpServletRequest request ,SeckillUser user,
                                 @RequestParam("goodsId")long goodsId,@RequestParam("verifyCode")Integer verifyCode){
        if(user != null){
            String redisCode = redisService.get(SeckillKey.getSeckillVerifyCode, user.getId()+"_"+goodsId);
            if(StringUtils.isNotBlank(redisCode)){
                Integer code = Integer.parseInt(redisCode);
                if(code != null && verifyCode != null && code - verifyCode == 0){
                    redisService.del(SeckillKey.getSeckillVerifyCode, user.getId()+"_"+goodsId);
                    // 加密path
                    String str = seckillService.createMiaoshaPath(user,goodsId);
                    return Result.success(str);
                }
                // 验证失败
                return Result.coderMsg(CodeMsg.VALIDATION_FAILS);
            }
            // 验证码失效
            return Result.coderMsg(CodeMsg.VERIFYCODE_FAILURE);
        }
        return Result.coderMsg(CodeMsg.SESSION_ERROR);
    }

    /**
     * 轮询是否秒杀成功
     * @param goodsId
     * @param user
     * @return -1 -> 秒杀失败 。 0 -> 排队中。 订单编号 -> 秒杀成功
     */
    @RequestMapping(value = "result.do",method = RequestMethod.GET)
    @ResponseBody
    public Result miaoshaResult(Long goodsId,SeckillUser user){
        if(user != null){
            return Result.success(seckillService.getMiaoshaResult(user.getId(),goodsId));
        }
        return Result.coderMsg(CodeMsg.SESSION_ERROR);
    }


}
